from datetime import datetime
import logging

from django.db import transaction
from rest_framework.views import APIView
from alipay import AliPay
from django.conf import settings
from rest_framework.response import Response
from order.models import Order
from rest_framework import status

from coupon.models import UserCoupon
from users.models import UserCourse

log = logging.getLogger('django')


class AlipayAPIView(APIView):
    def get(self,request):
        """获取支付宝的支付地址"""
        # 获取订单号
        order_number = request.query_params.get("order_number")
        # 判断订单是否存在
        try:
            order = Order.objects.get(order_number=order_number)
        except Order.DoesNotExist:
            return Response({"message": "对不起，订单不存在！"}, status=status.HTTP_400_BAD_REQUEST)

        # 初始化支付对象
        alipay = AliPay(
            appid=settings.ALIAPY_CONFIG["appid"],
            app_notify_url=settings.ALIAPY_CONFIG["app_notify_url"],  # 默认回调url
            # app_private_key_path=settings.ALIAPY_CONFIG["app_private_key_path"],
            app_private_key_string=open(settings.ALIAPY_CONFIG["app_private_key_path"]).read(),
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            # alipay_public_key_path=settings.ALIAPY_CONFIG["alipay_public_key_path"],
            alipay_public_key_string=open(settings.ALIAPY_CONFIG["alipay_public_key_path"]).read(),
            sign_type=settings.ALIAPY_CONFIG["sign_type"],
            debug=settings.ALIAPY_CONFIG["debug"]  # 默认False
        )

        # 调用接口
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order.order_number,
            total_amount=float(order.real_price),
            subject=order.order_title,
            return_url=settings.ALIAPY_CONFIG["return_url"],
            notify_url=settings.ALIAPY_CONFIG["notify_url"]  # 可选, 不填则使用默认notify url
        )

        url = settings.ALIAPY_CONFIG["gateway_url"] + order_string

        return Response(url)


class AliPayResultAPIView(APIView):
    def get(self, request):
        """处理支付宝同步通知结果"""
        datas = {'pay_time': '', 'pay_money': 0, 'course_list': []}
        # 初始化支付对象
        alipay = AliPay(
            appid=settings.ALIAPY_CONFIG["appid"],
            app_notify_url=settings.ALIAPY_CONFIG["app_notify_url"],  # 默认回调url
            app_private_key_string=open(settings.ALIAPY_CONFIG["app_private_key_path"]).read(),
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=open(settings.ALIAPY_CONFIG["alipay_public_key_path"]).read(),
            sign_type=settings.ALIAPY_CONFIG["sign_type"],
            debug=settings.ALIAPY_CONFIG["debug"]  # 默认False
        )

        data = request.query_params.dict()
        datas['pay_money'] = data.get('total_amount')
        signature = data.pop("sign")
        # verification
        success = alipay.verify(data, signature)
        if success:
            # 补充支付成功以后的代码
            order_number = data.get("out_trade_no")
            try:
                order = Order.objects.get(order_number=order_number, order_status=0)
            except Order.DoesNotExist:
                return Response({"message": "对不起，支付结果查询失败！订单不存在！"}, status=status.HTTP_400_BAD_REQUEST)

            with transaction.atomic():
                save_id = transaction.savepoint()
                # 更新订单状态、记录支付时间
                try:
                    order.pay_time = data.get('timestamp')
                    datas['pay_time'] = order.pay_time
                    order.order_status = 1
                    order.save()

                    # 如果有使用优惠券或者积分，则修改优惠券的使用状态和扣除积分
                    user_coupon_id = order.coupon
                    if user_coupon_id > 0:
                        user_coupon = UserCoupon.objects.get(pk=user_coupon_id,is_use=False, is_show=True, is_deleted=False)
                        user_coupon.is_use = True
                        user_coupon.save()

                    # 记录用户成功购买课程的记录, 增加课程的购买人数 记录用户购买的课程
                    order_detail_list = order.order_courses.all()
                    for order_detail in order_detail_list:
                        """循环本次订单中所有购买的商品课程"""
                        course = order_detail.course
                        datas['course_list'].append(course.name)
                        course.students += 1
                        course.save()
                        if order_detail.expire == 0:
                            out_time = '2099-01-01 00:00:00'
                        else:
                            out_time = datetime.now().timestamp() + order_detail.expire * 24 * 3600
                            out_time = datetime.fromtimestamp(out_time)
                            out_time = out_time.strftime("%Y-%m-%d %H:%M:%S")
                        UserCourse.objects.create(
                            user=order.user,
                            course=course,
                            trade_no=data.get('trade_no'),
                            pay_time=order.pay_time,
                            out_time=out_time,
                        )
                except:
                    log.error("订单结果处理出现故障!无法修改订单相关记录的状态")
                    transaction.savepoint_rollback(save_id)
                    return Response({"message": "对不起，更新订单相关记录失败！"},status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({"message": "支付成功！", 'data': datas})


# class AliPayResultAPIView(APIView):
#     def get(self, request):
#         """处理支付宝同步通知结果"""
#         datas = {'pay_time': '', 'pay_money': 0, 'course_list': []}
#         # 初始化支付对象
#         alipay = AliPay(
#             appid=settings.ALIAPY_CONFIG["appid"],
#             app_notify_url=settings.ALIAPY_CONFIG["app_notify_url"],  # 默认回调url
#             app_private_key_string=open(settings.ALIAPY_CONFIG["app_private_key_path"]).read(),
#             # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
#             alipay_public_key_string=open(settings.ALIAPY_CONFIG["alipay_public_key_path"]).read(),
#             sign_type=settings.ALIAPY_CONFIG["sign_type"],
#             debug=settings.ALIAPY_CONFIG["debug"]  # 默认False
#         )
#
#         data = request.query_params.dict()
#         datas['pay_money'] = data.get('total_amount')
#         print(data)
#         signature = data.pop("sign")
#         # verification
#         success = alipay.verify(data, signature)
#         if success:
#             # 补充支付成功以后的代码
#             order_number = data.get("out_trade_no")
#             try:
#                 order = Order.objects.get(order_number=order_number, order_status=0)
#             except Order.DoesNotExist:
#                 return Response({"message": "对不起，支付结果查询失败！订单不存在！"}, status=status.HTTP_400_BAD_REQUEST)
#
#             with transaction.atomic():
#                 save_id = transaction.savepoint()
#                 # 更新订单状态、记录支付时间
#                 try:
#                     order.pay_time = datetime.now()
#                     datas['pay_time'] = order.pay_time
#                     order.order_status = 1
#                     order.save()
#
#                     # 如果有使用优惠券或者积分，则修改优惠券的使用状态和扣除积分
#                     user_coupon_id = order.coupon
#                     if user_coupon_id > 0:
#                         user_coupon = UserCoupon.objects.get(pk=user_coupon_id,is_use=False, is_show=True, is_deleted=False)
#                         user_coupon.is_use = True
#                         user_coupon.save()
#
#                     # 记录用户成功购买课程的记录, 增加课程的购买人数 记录用户购买的课程
#                     order_detail_list = order.order_courses.all()
#                     for order_detail in order_detail_list:
#                         """循环本次订单中所有购买的商品课程"""
#                         course = order_detail.course
#                         datas['course_list'].append(course.name)
#                         course.students += 1
#                         course.save()
#                         if order_detail.expire == 0:
#                             out_time = '永久有效'
#                         else:
#                             out_time = datetime.now().timestamp() + order_detail.expire * 24 * 3600
#                             out_time = datetime.fromtimestamp(out_time)
#                             out_time = out_time.strftime("%Y-%m-%d %H:%M:%S")
#                         UserCourse.objects.create(
#                             user=order.user,
#                             course=course,
#                             trade_no=order.trade_no,
#                             pay_time=order.pay_time,
#                             out_time=out_time,
#                         )
#
#
#                 except:
#                     log.error("订单结果处理出现故障!无法修改订单相关记录的状态")
#                     transaction.savepoint_rollback(save_id)
#                     return Response({"message": "对不起，更新订单相关记录失败！"},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
#
#         return Response({"message": "支付成功！", 'data': datas})